package com.sadhoc.router.util;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

public abstract class ExpiringHashMap<k,v> extends HashMap<k, Integer> {

	private static final long serialVersionUID = -6474898719026303499L;
	
	private HashMap<k,v> data;
	private Object lock;
	private boolean changedFlag;
	
	public abstract void onRemoved(k key);
	
	public ExpiringHashMap() {
		super();
		data = new HashMap<k,v>();
		lock = new Object();
	}
	
	public void addEntry(k key, v value, int ms) {
		synchronized (lock) {
			data.put(key, value);
			put(key, ms);
		}
	}
		
	public void removeEntry(k key) {
		synchronized (lock) {
			data.remove(key);
			remove(key);
		}
	}
	
	public v getEntry(k key) {
		v r;
		synchronized (lock) {
			r = data.get(key);
		}
		return r;
	}
	
	public void updateEntry(k key, v value) {
		synchronized (lock) {
			data.put(key, value);
		}
	}
	
	public void updateTime(k key, int ms) {
		synchronized (lock) {
			put(key, ms);
		}
	}

	public HashMap<k,v> getCopyOfAllData() {
		HashMap<k,v> r;
		synchronized (lock) {
			r = new HashMap<k, v>(data);
		}
		return r;
	}
	
	public void decreaseAndRemoveEntry(int ms) {
		
		synchronized (lock) {
			
			Set<k> set = data.keySet();
		    Iterator<k> itr = set.iterator(); 
		    while (itr.hasNext()) 
		    { 
	        	k key = itr.next();
	        	int i = get(key);
	        	i = i - ms;
	        	if (i <= 0) {
	        		remove(key);
	        		itr.remove();
	        		onRemoved(key);
	        		setChangedFlag(true);
	        	}
	        	else {
	        		put(key, i);
	        	}
		    }			
		}	
		
	}
	
	public Object getLock() {
		return lock;
	}
	
	public synchronized boolean isChangedFlagSet() {
		return changedFlag;
	}
	
	public synchronized void setChangedFlag(boolean b) {
		changedFlag = b;
	}
	
	public Set<k> keySet() {
		return data.keySet();
	}
	

}
